
;;;
;;; FORWARD REFERENCES
;;;

;(define-imported-class short object)	;kluge!
;(define short (type-expression-value 'short))

(define short (type-expression-value 'short))

(define-imported-class (serialization-info "System.Runtime.Serialization.SerializationInfo") object
  (define (add-value (string name) (object value)) (public) void)
  (define (set-type (clr-type t)) (public) void))

(define-imported-class (streaming-context "System.Runtime.Serialization.StreamingContext") object)
(define-imported-class (i-serializable "System.Runtime.Serialization.ISerializable") object
  (define (get-object-data "System.Runtime.Serialization.ISerializable.GetObjectData"
			   (serialization-info info)
			   (streaming-context context))
    (public) void))

(define-imported-class meta-exception exception)
(define-imported-class (argument-exception (string mes)) exception)

(define-imported-class (argument-count-exception ((array object) arguments-provided)
					  ((array object) expected-arguments))
    argument-exception)

(define-imported-class (argument-type-exception (object argument-name)
				       (object value-provided)
				       (clr-type expected-type))
    argument-exception)

(define-imported-class (type-exception (string m_message)
				(object value-provided)
				(clr-type expected-type))
    argument-exception)

(define-imported-class (test-type-exception (string message)
					   (object value))
  type-exception)

(define-imported-class expression object)
  ;; Horrible kluge because define-imported-class is too stupid to handle
  ;; static members.
  (import (single-step-mode? "Expression.singleStepMode" boolean-type))
  (set (native-name (parse 'single-step-mode?)) "Expression.singleStepMode")

(define-imported-class environment object)
(define-imported-class marshal-by-ref-object object)
(define-imported-class procedure marshal-by-ref-object)
(define-imported-class procedure-placeholder procedure)

(define-imported-class i-arglist object
  (define (arglist "IArglist.Arglist") (property) (array object))
  (define (arglist-kluge "Arglist") (property) (array object)))
(set (keywords (parse 'arglist)) '(property))

(define-imported-class (i-comparer "System.Collections.IComparer") object
  (define (compare "System.Collections.IComparer.Compare"
		   (object x) (object y))
    (public) integer))
(set (keywords (parse 'compare)) '())

(define-imported-class i-documentable object
  (define (documentation "IDocumentable.Documentation") (property) string)
  (define (documentation-kluge "Documentation") (property) string))
(set (keywords (parse 'documentation)) '(property))

(define-imported-class (eval-stack) object
  (define arg-stack (public) (array object))
  (define (alloc-frame "AllocFrame" (short count)) (public) short)
  (define (set-expression! "SetExpression" (expression exp) (environment env))
    (public) void)
  (define (reset-stack! "ResetStackForTailCall" (object proc) (object args))
    (public) void)
  (define current-procedure "CurrentProcedure" (public) procedure)
  (define current-arguments "CurrentArguments" (public) (array object))
  (define breakpointed-frame? "BreakpointFrame" (public) boolean)
  (define (push "Push" (object proc) (object frame)) (public) void)
  (define (pop "Pop") (public) void)
  (define (pop-frame "PopFrame" (short frame)) (public) void))

(define-imported-class (execution-mode) object
  (define breakpoint "Breakpoint" (public) boolean)
  (define trace "Trace" (public) boolean)
  (define normal? "IsNormal" (public) boolean)
  (define (get-global-mode) (public) execution-mode)
  (define (check-normal) (public) boolean)
  (define (check-normal-2 "CheckNormal" (execution-mode proc))
    (public) boolean))

(define-imported-class (call-record (object proc) ((array object) args)) object
  (define call-result "Result" (public) object))

(define-imported-class (delegate) object)
(import-static (to-delegate "DelegateGenerator.AsDelegate"
			    (proc (clr-type procedure) (type-expression-value 'delegate)))
	       (remote? "Utilities.IsRemote" (proc (object) boolean))
	       (object->integer "System.Convert.ToInt32"
				(proc (object) integer)))

(%import-object 'current-thread-eval-stack
	 "EvalStack.CurrentThreadEvalStack"
	 (type-expression-value 'eval-stack))

(import (break "TopLevel.CurrentThreadTopLevel.BreakPoint" (proc (object object) void))
	(get-type-array "Type.GetTypeArray" (proc ((type-expression-value '(array object)))
						  (type-expression-value '(array clr-type))))
	(log-event "TopLevel.gui.Log" (proc (object) void))
	(call-handler "Meta.TopLevel.CallHandler"
		      (proc (object object object) object)))

(import-methods (get-method-from-arg-types "GetMethod"
					   (proc (clr-type string
					          (type-expression-value '(array clr-type)))
						 (type-expression-value 'method-info))))

;(define-imported-class (constant (object c)) expression)

(define-imported-class (exception (string mes)) object
  (define (message) (public virtual property) string))

(define-imported-class (missing-member-exception (string mes)) exception)

;;;
;;; HELPER MACRO FOR TRACED-CALL
;;;
(define-member-macro (make-traced-call untraced-name signature)
  (let ((arglist (cdr signature))
	(frame-size (length (cdr signature))))
    (let ((write-frame (let ((frame-offset 0))
			 (map (lambda (arg)
				(set! frame-offset (+ frame-offset 1))
				`(set (vector-ref (arg-stack estack)
						  (+ frame
						     (cast short
							   ,frame-offset)))
				      ,arg))
			      (cdr arglist)))))
      `(define (,(first signature) ,(second signature)
		  (eval-stack estack)
		  ,@(cddr signature))
	   "TracedCall" (public static object)
	   (let ((result null))
	     (let ((frame (alloc-frame estack
				       (cast short ,frame-size))))
	       (set (vector-ref (arg-stack estack) frame)
		    ,(- frame-size 1))
	       ,@write-frame
	       (now-calling! estack p frame
			     (let ((m (safe-check-mode p)))
			       (cond ((normal? m)
				      ;; FAST PATH
				      (set result (,untraced-name ,@arglist)))
				     (else
				      ;; SLOW PATH - used when tracing/breakpointing
				      (when (breakpoint m)
					(break null null))
				      (let ((t (call-record ,(second signature)
							    (new-array object
								       ,(length (cdr arglist))
								       ,@(cdr arglist)))))
					(when (trace m)
					  (log-event t))
					(set result (,untraced-name ,@arglist))
					(when (trace m)
					  (set (call-result t) result)))))))
	       (pop-frame estack frame)
	       result))))))

(define-member-macro (make-traced-call-no-stack untraced-name signature)
  (let ((arglist (cdr signature))
	(frame-size (length (cdr signature))))
    (let ((write-frame (let ((frame-offset 0))
			 (map (lambda (arg)
				(set! frame-offset (+ frame-offset 1))
				`(set (vector-ref (arg-stack estack)
						  (+ frame
						     (cast short
							   ,frame-offset)))
				      ,arg))
			      (cdr arglist)))))
      `(define (,(append->symbol (car signature)
				 "-no-stack")
		,@(cdr signature))
	 "TracedCall" (public static object)
	 (,(first signature) ,(second signature)
	  current-thread-eval-stack
	  ,@(cddr signature))))))

(define-member-macro (make-traced-call-no-stack-nonstatic untraced-name signature)
  (let ((arglist (cdr signature))
	(frame-size (length (cdr signature))))
    (let ((write-frame (let ((frame-offset 0))
			 (map (lambda (arg)
				(set! frame-offset (+ frame-offset 1))
				`(set (vector-ref (arg-stack estack)
						  (+ frame
						     (cast short
							   ,frame-offset)))
				      ,arg))
			      (cdr arglist)))))
      `(define (,(append->symbol (car signature)
				 "-no-stack-nonstatic")
		,@(cdr signature))
	 "TracedCall" (public object)
	 (,(first signature) ,(second signature)
	  current-thread-eval-stack
	  ,@(cddr signature))))))

(define-member-macro (make-traced-call-nonstatic untraced-name signature)
  (let ((arglist (cdr signature))
	(frame-size (length (cdr signature))))
    (let ((write-frame (let ((frame-offset 0))
			 (map (lambda (arg)
				(set! frame-offset (+ frame-offset 1))
				`(set (vector-ref (arg-stack estack)
						  (+ frame
						     (cast short
							   ,frame-offset)))
				      ,arg))
			      (cdr arglist)))))
      `(define (,(append->symbol (car signature)
				 "-nonstatic")
		(eval-stack estack)
		,@(cdr signature))
	 "TracedCall" (public object)
	 (,(first signature) estack ,@(cdr signature))))))
;;;
;;; HELPER MACRO FOR DELEGATE WRAPPERS
;;;

;(define-member-macro (define-handler-wrapper cname wname delegate-type args-type)
;  `(define (,wname this sender (,args-type args)) (public void)
;	    (traced-call2-no-stack this sender args)))
;;     (call-handler this sender args)))

;(define-member-macro (define-handler-constructor cname wname delegate-type args-type)
;  `(define (,cname this) (public property ,delegate-type)
;     (new ,delegate-type (,wname this))))

;; Put declarations for the handler wrappers here as if they were fields
(import-fields (%event-hndlr "EventHndlr" (proc (object) void))
	       (%key-event-hndlr "KeyEventHndlr" (proc (object) void))
	       (%key-press-event-hndlr "KeyPressEventHndlr" (proc (object) void))
	       (%mouse-event-hndlr "MouseEventHndlr" (proc (object) void))
	       (%paint-event-hndlr "PaintEventHndlr" (proc (object) void))
	       (%cancel-event-hndlr "CancelEventHndlr" (proc (object) void)))

;; And now the relevant types
(define-imported-class (event-handler (object o)) object)
(define-imported-class event-args object)
(define-imported-class (key-event-handler "System.Windows.Forms.KeyEventHandler" (object o)) object)
(define-imported-class (key-event-args "System.Windows.Forms.KeyEventArgs") object)
(define-imported-class (key-press-event-handler "System.Windows.Forms.KeyPressEventHandler" (object o)) object)
(define-imported-class (key-press-event-args "System.Windows.Forms.KeyPressEventArgs") object)
(define-imported-class (mouse-event-handler "System.Windows.Forms.MouseEventHandler" (object o)) object)
(define-imported-class (mouse-event-args "System.Windows.Forms.MouseEventArgs") object)
(define-imported-class (paint-event-handler "System.Windows.Forms.PaintEventHandler" (object o)) object)
(define-imported-class (paint-event-args "System.Windows.Forms.PaintEventArgs") object)
(define-imported-class (cancel-event-handler "System.ComponentModel.CancelEventHandler" (object o)) object)
(define-imported-class (cancel-event-args "System.ComponentModel.CancelEventArgs") object)

(import-methods (to-string "ToString" (proc (object) string)))

(define-module (lisp procedure)
  (define-class procedure (marshal-by-ref-object "IArglist" "IDocumentable"
						 "System.Collections.IComparer"
						 "System.Runtime.Serialization.ISerializable")
    ("[Serializable]")
    ;; Class stuff
    (define (wrong-number-of-args p ((array object) args))
      (protected object)
      (let ((a 1))
	(if (eq? a 1)
	    (throw (new argument-count-exception
			args
			(arglist-kluge (cast i-arglist p)))))
	null))
    (define (check-nargs p ((array object) args) (integer n))
      (protected void)
      (unless (= (length args) n)
	(wrong-number-of-args p args)))

    (define (safe-check-mode (procedure p)) (public static execution-mode)
      (if (remote? p)
	  (new execution-mode)
	  (let ((m (proc-execution-mode p)))
	    (get-global-mode m))))

    (define (get-object-data p info context)
      (add-value info "name" (procedure-name p))
      (add-value info "arglist" (arglist-kluge (cast i-arglist p)))
      (set-type info (type->clr-type procedure-placeholder)))

    ;; Instance fields
    (define proc-execution-mode "executionMode" (public execution-mode)
      (new execution-mode))
    (define (traced p) (public property boolean)
      (trace (proc-execution-mode p)))
    (define (breakpointed p) (public property boolean)
      (breakpoint (proc-execution-mode p)))
    (define (set-traced p (boolean t)) (public void)
      (set (trace (proc-execution-mode p)) t))
    (define (set-breakpointed p (boolean b)) (public void)
      (set (breakpoint (proc-execution-mode p)) b))

      
    (define setter (public procedure) null)

    ;; Reflection information
    (define (arglist p)
      (new-array object 0))
    (define (documentation p)
      (cast string null))
    (define procedure-name "name" (public object) s-unnamed)
    (define declared-type "DeclaredType" (public clr-type) null)
    (define declared-type "InferredType" (public clr-type) null)

    ;; Call interface
    (define (compare p (object x) (object y))
      (object->integer (traced-call2-no-stack p x y)))

    (define (apply p ((array object) args)) (public abstract object)
      null)
    (define (apply-one-way p ((array object) args))
      (public "[System.Runtime.Remoting.Messaging.OneWay]" void)
      (apply p args))

    (define (tail-apply p ((array object) args) (eval-stack estack)) (public virtual object)
      (apply p args))

    (define (maybe-apply-with-stack (procedure p) ((array object) args) (eval-stack estack))
      "Apply" (public static object)
      (if (remote? p)
	  (apply p args)
	  (apply-with-stack p args estack)))

    (define (apply-with-stack p ((array object) args) (eval-stack estack))
      "Apply" (public virtual object)
      (apply p args))

    (define (call0 p) "Call"
      (public abstract object) null)
    (define (call1 p arg1) "Call"
      (public abstract object) null)
    (define (call2 p arg1 arg2) "Call"
      (public abstract object) null)
    (define (call3 p arg1 arg2 arg3) "Call"
      (public abstract object) null)
    (define (call4 p arg1 arg2 arg3 arg4) "Call"
      (public abstract object) null)
    (define (call5 p arg1 arg2 arg3 arg4 arg5) "Call"
      (public abstract object) null)
    (define (call6 p arg1 arg2 arg3 arg4 arg5 arg6) "Call"
      (public abstract object) null)
    (define (call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7) "Call"
      (public abstract object) null)
    (define (call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8) "Call"
      (public abstract object) null)
    (define (call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9) "Call"
      (public abstract object) null)
    (define (call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10)
      "Call" (public abstract object) null)
    (define (call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11)
      "Call" (public abstract object) null)
    (define (call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12)
      "Call" (public abstract object) null)
    (define (call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13)
      "Call" (public abstract object) null)
    (define (call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14)
      "Call" (public abstract object) null)
    (define (call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15)
      "Call" (public abstract object) null)
    (define (call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16)
      "Call" (public abstract object) null)
    (define (call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17)
      "Call" (public abstract object) null)
    (define (call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18)
      "Call" (public abstract object) null)
    (define (call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19)
      "Call" (public abstract object) null)
    (define (call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20)
      "Call" (public abstract object) null)

    (define (traced-apply p (eval-stack estack) ((array object) args))
      (public static object)
      (now-calling estack p args
		   (let ((result null)
			 (m (safe-check-mode p)))
		     (cond ((normal? m)
			    (set result (maybe-apply-with-stack p args estack)))
			   (else
			    (when (breakpoint m)
			      (break null null))
			    (let ((t (call-record p args)))
			      (when (trace m)
				(log-event t))
			      (set result (maybe-apply-with-stack p args estack))
			      (when (trace m)
				(set (call-result t) result)))))
		     result)))

;      (now-calling estack p args
;		   (when (not (check-normal (proc-execution-mode p)))
;		     (break null null))
;		   (let ((retval (apply-with-stack p args estack)))
;		     (when  (not (check-normal (proc-execution-mode p)))
;		       (now-calling! estack null (new-array object 1 retval)
;				     (break null null)))
;		     retval)))

    ;; Debugging interface
    (define (traced-apply-no-stack p ((array object) args)) "TracedApply"
      (public static object)
      (traced-apply p current-thread-eval-stack args))

    (make-traced-call call0 (traced-call0 p))
    (make-traced-call call1 (traced-call1 p arg1))
    (make-traced-call call2 (traced-call2 p arg1 arg2))

    (make-traced-call call3 (traced-call3 p arg1 arg2 arg3))
    (make-traced-call call4 (traced-call4 p arg1 arg2 arg3 arg4))
    (make-traced-call call5 (traced-call5 p arg1 arg2 arg3 arg4 arg5))
    (make-traced-call call6 (traced-call6 p arg1 arg2 arg3 arg4 arg5 arg6))
    (make-traced-call call7 (traced-call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7))
    (make-traced-call call8 (traced-call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8))
    (make-traced-call call9 (traced-call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9))
    (make-traced-call call10 (traced-call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10))
    (make-traced-call call11 (traced-call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11))
    (make-traced-call call12 (traced-call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12))
    (make-traced-call call13 (traced-call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13))
    (make-traced-call call14 (traced-call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14))
    (make-traced-call call15 (traced-call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15))
    (make-traced-call call16 (traced-call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16))
    (make-traced-call call17 (traced-call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16 arg17))
    (make-traced-call call18 (traced-call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18))
    (make-traced-call call19 (traced-call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19))
    (make-traced-call call20 (traced-call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20))

;    (make-traced-call-nonstatic call0 (traced-call0 p))
;    (make-traced-call-nonstatic call1 (traced-call1 p arg1))
;    (make-traced-call-nonstatic call2 (traced-call2 p arg1 arg2))

;    (make-traced-call-nonstatic call3 (traced-call3 p arg1 arg2 arg3))
;    (make-traced-call-nonstatic call4 (traced-call4 p arg1 arg2 arg3 arg4))
;    (make-traced-call-nonstatic call5 (traced-call5 p arg1 arg2 arg3 arg4 arg5))
;    (make-traced-call-nonstatic call6 (traced-call6 p arg1 arg2 arg3 arg4 arg5 arg6))
;    (make-traced-call-nonstatic call7 (traced-call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7))
;    (make-traced-call-nonstatic call8 (traced-call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8))
;    (make-traced-call-nonstatic call9 (traced-call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9))
;    (make-traced-call-nonstatic call10 (traced-call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10))
;    (make-traced-call-nonstatic call11 (traced-call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11))
;    (make-traced-call-nonstatic call12 (traced-call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12))
;    (make-traced-call-nonstatic call13 (traced-call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13))
;    (make-traced-call-nonstatic call14 (traced-call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14))
;    (make-traced-call-nonstatic call15 (traced-call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15))
;    (make-traced-call-nonstatic call16 (traced-call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16))
;    (make-traced-call-nonstatic call17 (traced-call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17))
;    (make-traced-call-nonstatic call18 (traced-call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18))
;    (make-traced-call-nonstatic call19 (traced-call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19))
;    (make-traced-call-nonstatic call20 (traced-call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20))


    (make-traced-call-no-stack call0 (traced-call0 p))
    (make-traced-call-no-stack call1 (traced-call1 p arg1))
    (make-traced-call-no-stack call2 (traced-call2 p arg1 arg2))

    (make-traced-call-no-stack call3 (traced-call3 p arg1 arg2 arg3))
    (make-traced-call-no-stack call4 (traced-call4 p arg1 arg2 arg3 arg4))
    (make-traced-call-no-stack call5 (traced-call5 p arg1 arg2 arg3 arg4 arg5))
    (make-traced-call-no-stack call6 (traced-call6 p arg1 arg2 arg3 arg4 arg5 arg6))
    (make-traced-call-no-stack call7 (traced-call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7))
    (make-traced-call-no-stack call8 (traced-call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8))
    (make-traced-call-no-stack call9 (traced-call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9))
    (make-traced-call-no-stack call10 (traced-call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10))
    (make-traced-call-no-stack call11 (traced-call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11))
    (make-traced-call-no-stack call12 (traced-call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12))
    (make-traced-call-no-stack call13 (traced-call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13))
    (make-traced-call-no-stack call14 (traced-call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14))
    (make-traced-call-no-stack call15 (traced-call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15))
    (make-traced-call-no-stack call16 (traced-call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16))
    (make-traced-call-no-stack call17 (traced-call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16 arg17))
    (make-traced-call-no-stack call18 (traced-call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18))
    (make-traced-call-no-stack call19 (traced-call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19))
    (make-traced-call-no-stack call20 (traced-call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20))

;    (make-traced-call-no-stack-nonstatic call0 (traced-call0 p))
;    (make-traced-call-no-stack-nonstatic call1 (traced-call1 p arg1))
;    (make-traced-call-no-stack-nonstatic call2 (traced-call2 p arg1 arg2))

;    (make-traced-call-no-stack-nonstatic call3 (traced-call3 p arg1 arg2 arg3))
;    (make-traced-call-no-stack-nonstatic call4 (traced-call4 p arg1 arg2 arg3 arg4))
;    (make-traced-call-no-stack-nonstatic call5 (traced-call5 p arg1 arg2 arg3 arg4 arg5))
;    (make-traced-call-no-stack-nonstatic call6 (traced-call6 p arg1 arg2 arg3 arg4 arg5 arg6))
;    (make-traced-call-no-stack-nonstatic call7 (traced-call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7))
;    (make-traced-call-no-stack-nonstatic call8 (traced-call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8))
;    (make-traced-call-no-stack-nonstatic call9 (traced-call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9))
;    (make-traced-call-no-stack-nonstatic call10 (traced-call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10))
;    (make-traced-call-no-stack-nonstatic call11 (traced-call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11))
;    (make-traced-call-no-stack-nonstatic call12 (traced-call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12))
;    (make-traced-call-no-stack-nonstatic call13 (traced-call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13))
;    (make-traced-call-no-stack-nonstatic call14 (traced-call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14))
;    (make-traced-call-no-stack-nonstatic call15 (traced-call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15))
;    (make-traced-call-no-stack-nonstatic call16 (traced-call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16))
;    (make-traced-call-no-stack-nonstatic call17 (traced-call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17))
;    (make-traced-call-no-stack-nonstatic call18 (traced-call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18))
;    (make-traced-call-no-stack-nonstatic call19 (traced-call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19))
;    (make-traced-call-no-stack-nonstatic call20 (traced-call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20))


;    (define (traced-call0 p) "TracedCall"
;      (public object)
;      (call0 p))
;    (define (traced-call1 p arg1) "TracedCall"
;      (public object)
;      (call1 p arg1))
;    (define (traced-call2 p arg1 arg2) "TracedCall"
;      (public object)
;      (call2 p arg1 arg2))
;    (define (traced-call3 p arg1 arg2 arg3) "TracedCall"
;      (public object)
;      (call3 p arg1 arg2 arg3))
;    (define (traced-call4 p arg1 arg2 arg3 arg4) "TracedCall"
;      (public object)
;      (call4 p arg1 arg2 arg3 arg4))
;    (define (traced-call5 p arg1 arg2 arg3 arg4 arg5) "TracedCall"
;      (public object)
;      (call5 p arg1 arg2 arg3 arg4 arg5))
;    (define (traced-call6 p arg1 arg2 arg3 arg4 arg5 arg6) "TracedCall"
;      (public object)
;      (call6 p arg1 arg2 arg3 arg4 arg5 arg6))
;    (define (traced-call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7) "TracedCall"
;      (public object)
;      (call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7))
;    (define (traced-call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8) "TracedCall"
;      (public object)
;      (call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8))
;    (define (traced-call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9) "TracedCall"
;      (public object)
;      (call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9))
;    (define (traced-call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10)
;      "TracedCall" (public object)
;      (call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10))
;    (define (traced-call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11)
;      "TracedCall" (public object)
;      (call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	     arg11))
;    (define (traced-call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12)
;      "TracedCall" (public object)
;      (call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	     arg11 arg12))
;    (define (traced-call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13)
;      "TracedCall" (public object)
;      (call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	     arg11 arg12 arg13))
;    (define (traced-call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14)
;      "TracedCall" (public object)
;      (call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	     arg11 arg12 arg13 arg14))
;    (define (traced-call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15)
;      "TracedCall" (public object)
;      (call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	     arg11 arg12 arg13 arg14 arg15))
;    (define (traced-call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16)
;      "TracedCall" (public object)
;      (call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	     arg11 arg12 arg13 arg14 arg15 arg16))
;    (define (traced-call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17)
;      "TracedCall" (public object)
;      (call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	      arg11 arg12 arg13 arg14 arg15 arg16 arg17))
;    (define (traced-call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18)
;      "TracedCall" (public object)
;      (call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	      arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18))
;    (define (traced-call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19)
;      "TracedCall" (public object)
;      (call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	      arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19))
;    (define (traced-call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;			   arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20)
;      "TracedCall" (public object)
;      (call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
;	      arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20))

    ;;;
    ;;; Wrappers for event handlers
    ;;;

;    (define-handler-wrapper as-event-handler event-hndlr event-handler event-args)
;    (define-handler-constructor as-event-handler %event-hndlr event-handler event-args)
;    (define-handler-wrapper as-key-event-handler key-event-hndlr key-event-handler key-event-args)
;    (define-handler-constructor as-key-event-handler %key-event-hndlr key-event-handler key-event-args)
;    (define-handler-wrapper as-key-press-event-handler key-press-event-hndlr key-press-event-handler key-press-event-args)
;    (define-handler-constructor as-key-press-event-handler %key-press-event-hndlr key-press-event-handler key-press-event-args)
;    (define-handler-wrapper as-mouse-event-handler mouse-event-hndlr mouse-event-handler mouse-event-args)
;    (define-handler-constructor as-mouse-event-handler %mouse-event-hndlr mouse-event-handler mouse-event-args)
;    (define-handler-wrapper as-paint-event-handler paint-event-hndlr paint-event-handler paint-event-args)
;    (define-handler-constructor as-paint-event-handler %paint-event-hndlr paint-event-handler paint-event-args)
;    (define-handler-wrapper as-cancel-event-handler cancel-event-hndlr cancel-event-handler cancel-event-args)
;    (define-handler-constructor as-cancel-event-handler %cancel-event-hndlr cancel-event-handler cancel-event-args)

    (define (as-delegate p (clr-type t)) (public delegate)
      (to-delegate t p))
    )


  (define-class apply-interface-procedure procedure
    ("[Serializable]")
    ;; Call interface
    (define (call0 p)
					;"Call" (public override object)
      (apply p (new-array object 0)))
    (define (call1 p arg1)
					; "Call" (public override object)
      (apply p (new-array object 1 arg1)))
    (define (call2 p arg1 arg2)
					; "Call" (public override object)
      (apply p (new-array object 2 arg1 arg2)))
    (define (call3 p arg1 arg2 arg3)
					; "Call" (public override object)
      (apply p (new-array object 3 arg1 arg2 arg3)))
    (define (call4 p arg1 arg2 arg3 arg4)
					;"Call" (public override object)
      (apply p (new-array object 4 arg1 arg2 arg3 arg4)))
    (define (call5 p arg1 arg2 arg3 arg4 arg5)
					; "Call" (public override object)
      (apply p (new-array object 5 arg1 arg2 arg3 arg4 arg5)))
    (define (call6 p arg1 arg2 arg3 arg4 arg5 arg6)
					; "Call" (public override object)
      (apply p (new-array object 6 arg1 arg2 arg3 arg4 arg5 arg6)))
    (define (call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7)
					; "Call" (public override object)
      (apply p (new-array object 7 arg1 arg2 arg3 arg4 arg5 arg6 arg7)))
    (define (call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8)
					;"Call" (public override object)
      (apply p (new-array object 8 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8)))
    (define (call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9)
					;"Call" (public override object)
      (apply p
	     (new-array object 9
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9)))
    (define (call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10)
					;"Call" (public override object)
      (apply p
	     (new-array object 10
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10)))
    (define (call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11)
					;"Call" (public override object)
      (apply p
	     (new-array object 11
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11)))
    (define (call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12)
					;"Call" (public override object)
      (apply p
	     (new-array object 12
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12)))
    (define (call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13)
					;"Call" (public override object)
      (apply p
	     (new-array object 13
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12 arg13)))
    (define (call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14)
					;"Call" (public override object)
      (apply p
	     (new-array object 14
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12 arg13 arg14)))
    (define (call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15)
					;"Call" (public override object)
      (apply p
	     (new-array object 15
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12 arg13 arg14 arg15)))
    (define (call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16)
					;"Call" (public override object)
      (apply p
	     (new-array object 16
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12 arg13 arg14 arg15 arg16)))
    (define (call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17)
					;"Call" (public override object)
      (apply p
	     (new-array object 17
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12 arg13 arg14 arg15 arg16 arg17)))
    (define (call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18)
					;"Call" (public override object)
      (apply p
	     (new-array object 18
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18)))
    (define (call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19)
					;"Call" (public override object)
      (apply p
	     (new-array object 19
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18
			arg19)))
    (define (call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20)
					;"Call" (public override object)
      (apply p
	     (new-array object 20
			arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
			arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18
			arg19 arg20))))

  (define-class call-interface-procedure procedure
    ("[Serializable]")
    ;; Call interface
    (define (apply p ((array object) args))
					;(public override object)
      (let ((nargs (length args)))
	(cond ((= nargs 0)
	       (call0 p))
	      ((= nargs 1)
	       (call1 p (vector-ref args 0)))
	      ((= nargs 2)
	       (call2 p (vector-ref args 0) (vector-ref args 1)))
	      ((= nargs 3)
	       (call3 p (vector-ref args 0) (vector-ref args 1)
		      (vector-ref args 2)))
	      ((= nargs 4)
	       (call4 p (vector-ref args 0) (vector-ref args 1)
		      (vector-ref args 2) (vector-ref args 3)))
	      ((= nargs 5)
	       (call5 p (vector-ref args 0) (vector-ref args 1)
		      (vector-ref args 2) (vector-ref args 3)
		      (vector-ref args 4)))
	      ((= nargs 6)
	       (call6 p (vector-ref args 0) (vector-ref args 1)
		      (vector-ref args 2) (vector-ref args 3)
		      (vector-ref args 4) (vector-ref args 5)))
	      ((= nargs 7)
	       (call7 p (vector-ref args 0) (vector-ref args 1)
		      (vector-ref args 2) (vector-ref args 3)
		      (vector-ref args 4) (vector-ref args 5)
		      (vector-ref args 6)))
	      ((= nargs 8)
	       (call8 p (vector-ref args 0) (vector-ref args 1)
		      (vector-ref args 2) (vector-ref args 3)
		      (vector-ref args 4) (vector-ref args 5)
		      (vector-ref args 6) (vector-ref args 7)))
	      ((= nargs 9)
	       (call9 p (vector-ref args 0) (vector-ref args 1)
		      (vector-ref args 2) (vector-ref args 3)
		      (vector-ref args 4) (vector-ref args 5)
		      (vector-ref args 6) (vector-ref args 7)
		      (vector-ref args 8)))
	      ((= nargs 10)
	       (call10 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)))
	      ((= nargs 11)
	       (call11 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10)))
	      ((= nargs 12)
	       (call12 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)))
	      ((= nargs 13)
	       (call13 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)
		       (vector-ref args 12)))
	      ((= nargs 14)
	       (call14 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)
		       (vector-ref args 12) (vector-ref args 13)))
	      ((= nargs 15)
	       (call15 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)
		       (vector-ref args 12) (vector-ref args 13)
		       (vector-ref args 14)))
	      ((= nargs 16)
	       (call16 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)
		       (vector-ref args 12) (vector-ref args 13)
		       (vector-ref args 14) (vector-ref args 15)))
	      ((= nargs 17)
	       (call17 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)
		       (vector-ref args 12) (vector-ref args 13)
		       (vector-ref args 14) (vector-ref args 15)
		       (vector-ref args 16)))
	      ((= nargs 18)
	       (call18 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)
		       (vector-ref args 12) (vector-ref args 13)
		       (vector-ref args 14) (vector-ref args 15)
		       (vector-ref args 16) (vector-ref args 17)))
	      ((= nargs 19)
	       (call19 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)
		       (vector-ref args 12) (vector-ref args 13)
		       (vector-ref args 14) (vector-ref args 15)
		       (vector-ref args 16) (vector-ref args 17)
		       (vector-ref args 18)))
	      ((= nargs 20)
	       (call20 p (vector-ref args 0) (vector-ref args 1)
		       (vector-ref args 2) (vector-ref args 3)
		       (vector-ref args 4) (vector-ref args 5)
		       (vector-ref args 6) (vector-ref args 7)
		       (vector-ref args 8) (vector-ref args 9)
		       (vector-ref args 10) (vector-ref args 11)
		       (vector-ref args 12) (vector-ref args 13)
		       (vector-ref args 14) (vector-ref args 15)
		       (vector-ref args 16) (vector-ref args 17)
		       (vector-ref args 18) (vector-ref args 19)))
	      (else
	       (wrong-number-of-args p args)))))

    (define (call0 p)
					;"Call" (public override object)
      (wrong-number-of-args p (new-array object 0)))
    (define (call1 p arg1)
					;"Call" (public override object)
      (wrong-number-of-args p (new-array object 1 arg1)))
    (define (call2 p arg1 arg2)
					;"Call" (public override object)
      (wrong-number-of-args p (new-array object 2 arg1 arg2)))
    (define (call3 p arg1 arg2 arg3)
					;"Call (public override object)
      (wrong-number-of-args p (new-array object 3 arg1 arg2 arg3)))
    (define (call4 p arg1 arg2 arg3 arg4)
					;"Call" (public override object)
      (wrong-number-of-args p (new-array object 4 arg1 arg2 arg3 arg4)))
    (define (call5 p arg1 arg2 arg3 arg4 arg5)
					;"Call" (public override object)
      (wrong-number-of-args p (new-array object 5 arg1 arg2 arg3 arg4 arg5)))
    (define (call6 p arg1 arg2 arg3 arg4 arg5 arg6)
					;"Call" (public override object)
      (wrong-number-of-args p (new-array object 6 arg1 arg2 arg3 arg4 arg5 arg6)))
    (define (call7 p arg1 arg2 arg3 arg4 arg5 arg6 arg7)
					;"Call" (public override object)
      (wrong-number-of-args p (new-array object 7 arg1 arg2 arg3 arg4 arg5 arg6 arg7)))
    (define (call8 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8)
					;"Call" (public override object)
      (wrong-number-of-args p (new-array object 8 arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8)))
    (define (call9 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 9
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9)))
    (define (call10 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 10
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10)))
    (define (call11 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 11
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11)))
    (define (call12 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 12
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12)))
    (define (call13 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 13
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12 arg13)))
    (define (call14 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 14
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12 arg13 arg14)))
    (define (call15 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 15
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12 arg13 arg14 arg15)))
    (define (call16 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 16
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12 arg13 arg14 arg15 arg16)))
    (define (call17 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 17
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12 arg13 arg14 arg15 arg16 arg17)))
    (define (call18 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 18
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18)))
    (define (call19 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 19
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18
				       arg19)))
    (define (call20 p arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8 arg9 arg10
                    arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18 arg19 arg20)
					;"Call" (public override object)
      (wrong-number-of-args p
			    (new-array object 20
				       arg1 arg2 arg3 arg4 arg5 arg6 arg7 arg8	arg9 arg10
				       arg11 arg12 arg13 arg14 arg15 arg16 arg17 arg18
				       arg19 arg20))))

;  (define-class settable procedure
;    (define (setter ((array object) args) (object new-value))
;      (public abstract object)
;      null))

  (define-class (left-curried-procedure proc args) apply-interface-procedure
    ("[Serializable]")
    (define proc (private procedure) null)
    (define args (private (array object)) null)

    (define (apply curried more-args)
      (apply (proc curried)
	     (append2 (cast ilist (args curried))
		      (cast ilist more-args)))))

  (define-class (right-curried-procedure proc args) apply-interface-procedure
    ("[Serializable]")
    (define proc (private procedure) null)
    (define args (private (array object)) null)

    (define (apply curried more-args)
      (apply (proc curried)
	     (append2 (cast ilist more-args)
		      (cast ilist (args curried))))))

  (define-class (field-wrapper procedure-name field) (call-interface-procedure "IArglist")
    ("[Serializable]")
    (define field (public field-info) null)
    (define (field-of (clr-type type) (string name))
      (public static object)
      (new field-wrapper
	   (intern name)
	   (get-field type name)))
    (define (call1 f obj)
      (get-field-value (field f) obj))
    (define (arglist f)
      (new-array object 1
		 (intern (type-name (declaring-type (field f)))))))

  (define-class (property-wrapper procedure-name property) (call-interface-procedure "IArglist")
    ("[Serializable]")
    (define property (public property-info) null)
    (define (property-of (clr-type type) (string name))
      (public static object)
      (new property-wrapper
	   (intern name)
	   (get-property type name)))
    (define no-args (private static (array object))
      (new-array object 0))
    (define (call1 f obj)
      (get-property-value (property f) obj no-args))
    (define (arglist f)
      (new-array object 1
		 (intern (type-name (declaring-type (property f)))))))

  (define-class (method-wrapper procedure-name method) (apply-interface-procedure "IArglist")
    ("[Serializable]")
    (define method (public method-info) null)
    (define (method-of (clr-type type) (string name))
      (public static object)
      (new method-wrapper
	   (intern name)
	   (get-method type name)))
    (define (apply f args)
      (let ((obj (vector-ref args 0))
	    (len (- (length args) 1)))
	(let ((real-args (new-array object len)))	      
	  (copy-subarray args 1 real-args 0 len)
	  (invoke-method (method f) obj real-args))))
    (define (arglist f)
      (if (null? (method f))
	  (new-array object 0)
	  (let ((paraminfos (get-parameters (method f))))
	    (if (null? paraminfos)
		(new-array object 0)
		(let ((arglist (new-array object (+ (length paraminfos)
						    1))))
		  (set (vector-ref arglist 0)
		       (intern (type-name (declaring-type (method f)))))
		  (dotimes (i (length paraminfos))
		    (set (vector-ref arglist (+ i 1))
			 (intern (parameter-name (vector-ref paraminfos i)))))
		  arglist))))))

  (define-class (closed-method-wrapper procedure-name obj method) (apply-interface-procedure "IArglist")
    ("[Serializable]")
    (define method (public method-info) null)
    (define obj "methodTarget" (public object) null)
    (define (method-of (clr-type type) (string name))
      (public static object)
      (new method-wrapper
	   (intern name)
	   (get-method type name)))
    (define (apply f args)
      (invoke-method (method f)
		     (obj f)
		     args))
    (define (arglist f)
      (let ((paraminfos (get-parameters (method f))))
	(let ((arglist (new-array object (length paraminfos))))
	  (dotimes (i (length paraminfos))
	    (set (vector-ref arglist i)
		 (intern (parameter-name (vector-ref paraminfos i)))))
	  arglist))))

  (define-class (closed-ambiguous-method-wrapper procedure-name obj method-name) (apply-interface-procedure "IArglist")
    ("[Serializable]")
    (define method-name (public string) null)
    (define obj "methodTarget" (public object) null)
    (define (apply f args)
;      Always generates MissingMethodException for some reason
;      (invoke-member (type-of (obj f))
;		     (method-name f)
;		     (bitwise-or public invoke-method)
;		     null
;		     (obj f)
;		     args))
      (let ((method (get-method-from-arg-types (type-of (obj f))
					       (method-name f)
					       (get-type-array args))))
	(if (null? method)
	    (throw (new missing-member-exception
			"Couldn't find a method to match the provided argument types")))
	(invoke-method method
		       (obj f)
		       args)))
    (define (arglist f)
      (new-array object 2
		 (intern "arg")
		 (intern "..."))))

  (define-class (closed-ambiguous-static-method-wrapper procedure-name typ method-name) (apply-interface-procedure "IArglist")
    ("[Serializable]")
    (define method-name (public string) null)
    (define typ "methodTarget" (public clr-type) null)
    (define (apply f args)
      (invoke-member (typ f)
		     (method-name f)
		     (bitwise-or public (bitwise-or static invoke-method))
		     null
		     (typ f)
		     args))
    (define (arglist f)
      (new-array object 2
		 (intern "arg")
		 (intern "...")))))